package locpris.swan.ac.uk;

import java.awt.Font;
import java.util.ArrayList;

import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.image.Texture2D;
import com.jme.math.FastMath;
import com.jme.math.Matrix3f;
import com.jme.math.Quaternion;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Circle;
import com.jme.scene.Line;
import com.jme.scene.TexCoords;
import com.jme.scene.TriMesh;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Cylinder;
import com.jme.scene.shape.Sphere;
import com.jme.util.geom.BufferUtils;
import com.jmex.font3d.Font3D;
import com.jmex.font3d.Text3D;

/*
 * A AccessPoint
 */
public class AccessPoint extends ANode {
	
	//local variables of and AP
	private Cylinder aAP = new Cylinder("AP",20,20,2,3,true,false);
	//ap height by default
	private float apHeight = 3.5f; 
	private float apRadius = 0.75f;
	//list of neighbours
	private ArrayList<Neighbour> neighbourList = new ArrayList<Neighbour>();
	//radius
	private int radius=5;
	

	public Circle setSignalRadius2D(int rsradius, Vector3f startPosition)
	{
		Circle rssr = new Circle("rssr",20,rsradius);
		Quaternion q = new Quaternion();
		//rotate the rssr to be vertical
		q.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
		rssr.setLocalRotation(q);
		Vector3f rssrloc = new Vector3f(0,0,0);
		rssrloc = rssrloc.add(startPosition);
		rssrloc.setY(0);
		System.out.println("rssrloc="+rssrloc);
		rssr.setLocalTranslation(rssrloc);
		rssr.setLineWidth(2f);
		rssr.setDefaultColor(nodeColour);
		rssr.setMode(Line.Mode.Loop);
		rssr.setSolidColor(nodeColour);
		return rssr;
	}
	
	public Circle setSignalRadius3D(int rsradius, Vector3f startPosition)
	{
		Circle rssr = new Circle("rssr",20,rsradius);
		Quaternion q = new Quaternion();
		//rotate the rssr to be vertical
		q.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
		rssr.setLocalRotation(q);
		Vector3f rssrloc = new Vector3f(0,0,0);
		rssrloc = rssrloc.add(startPosition);
		rssrloc.setY(rssrloc.y - apHeight /2);
		System.out.println("rssrloc="+rssrloc);
		rssr.setLocalTranslation(rssrloc);
		rssr.setLineWidth(2f);
		rssr.setDefaultColor(nodeColour);
		rssr.setMode(Line.Mode.Loop);
		rssr.setSolidColor(nodeColour);
		return rssr;
	}
	
	public AccessPoint(Vector3f startPosition,int radius, String name, String dimension,boolean proxied)
	{
		this.nodeName = name;
		if (proxied) {
			this.setColour("blue");
			aAP.setDefaultColor(nodeColour);
		}
		else
		{
			this.setColour("green");
			aAP.setDefaultColor(nodeColour);
		}
		//subtract apheight/2 from y to adjust for rotation of AP
		
		//
		//below code could be made redundant by changelocation method
		//
		
		startPosition.setY(startPosition.y + (apHeight/2));
		this.setLocation(startPosition);
		aAP.updateGeometry(20,20,apRadius,0,apHeight,true,false);
		aAP.setLocalTranslation(startPosition);
		System.out.println("AP Location="+startPosition);
		Quaternion q = new Quaternion();
		//rotate the ap to be vertical
		q.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
		//aAP.setLocalRotation(new Matrix3f(0,0,0,0,0,0,1.5f,2f,0.5f));
		aAP.setLocalRotation(q);
		Circle rssr ;
		this.radius = radius;
		if (dimension.equals("2d")) { rssr = setSignalRadius2D(radius,startPosition); }
		else { rssr = setSignalRadius3D(radius,startPosition); }
		System.out.println("AP Location2="+startPosition);
		//test name of ap
		//Font3D font = new Font3D(new Font("Arial", Font.PLAIN, 24), 0.001f, true, true, true);
		//Text3D text = font.createText(nodeName, 10.0f, 0);
		//startPosition.add(0,-2,0);
		//text.setLocalScale(startPosition);
		//nodes.attachChild(text);
		nodes.attachChild(rssr);
		nodes.attachChild(aAP);
		addToRoot();
	}
	
	public void changeLocation(Vector3f loc,boolean proxied)
	{
		nodes.detachAllChildren();
		
		if (proxied) {
			this.setColour("blue");
			aAP.setDefaultColor(nodeColour);
		}
		else
		{
			this.setColour("red");
			aAP.setDefaultColor(nodeColour);
		}
		this.setLocation(loc);
		numberNodes = getNumberOfNodes();
		Quaternion q = new Quaternion();
		//rotate the ap to be vertical
		q.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
		//aAP.setLocalRotation(new Matrix3f(0,0,0,0,0,0,1.5f,2f,0.5f));
		aAP.setLocalRotation(q);
		Circle rssr ;
		rssr = setSignalRadius2D(radius,loc);
		//draw line to neighbour
		Neighbour temp = null;
		int len = neighbourList.size();
		for (int n =0; n < len; n++)
		{
			temp = neighbourList.get(n);
			if (temp.getNeighbourName().equals(this.nodeName)) 
			{ 
				//itself
			}
			else
			{
				//draw link to neighbour
				this.addNodeLocation(temp.getLocation());
			}
		}
	
		aAP.updateGeometry(20,20,apRadius,0,apHeight,true,false);
		aAP.setLocalTranslation(loc);
		nodes.attachChild(rssr);
		nodes.attachChild(aAP);
		addToRoot();
	}
	
	public boolean setNeighbour(String apname, int weight, Vector3f neighbourloc)
	{
		//check if neighbour in neighbour list
		Neighbour temp = null;
		boolean better = false;
		int found = 0;
		int len = neighbourList.size();
		for (int n =0; n < len; n++)
		{
			temp = neighbourList.get(n);
			if (temp.getNeighbourName().equals(apname)) { found=1; break;}
		}
		if (found==1)
		{
			//already neighbours, check if better
			better = temp.newWeight(weight);
			if (better) temp.setLocation(neighbourloc);
		}
		else
		{
			//new neighbour
			Neighbour newNeighbour = new Neighbour(apname,weight,neighbourloc);
			neighbourList.add(newNeighbour);
			better = true;
		}
		return better;
	}
	
	public int getNumberNeighbours()
	{
		return neighbourList.size();
	}
	
	public Neighbour getNeighbour(int neigh)
	{
		if (neighbourList.size()>=neigh) return neighbourList.get(neigh);
		else return null;
	}
	
	public void buildAP()
	{



	}
}
